Hello. I’m Thomas Wang (also known as Xi Ye).
In Part 1, I used mind maps to summarize WAAPI essentials. With the development environment configured, I wrote several short scripts with Python. And we had a first taste of the power of WAAPI.
Starting from Part 2, we will go through all the branches of WAAPI. To make this easier to read, I will do my best to describe them as simply as possible and demonstrate real API use cases.
I also created a repository on GitHub for easy access. You will find all the code referred to in this blog series.
https://github.com/zcyh147/Everyone-can-use-WAAPI
Before we proceed, there a few things things that I want to clarify:
- The main purpose of listing the APIs here is to clarify their usage, and get you up and running quickly. It’s recommended that you make your own list according to the description in Part 1.
- This blog assumes that you’ve gone through Part 1, knowing how to use those tips and tricks such as formatting the JSON syntax for better readability, looking up the WAAPI arguments and return values, etc. Still, I suggest you check the online documents while reading this blog.
- For the sake of beginners, I tried to add notes to each line to address more details.
- Try to do some investigation before you raise a question. Wwise documents and Google search are more powerful than you can imagine.
- WAAPI features will be updated over time, make sure you install the latest version of Wwise. When the “The procedure URI is unknown.” error message occurs, it means your APIs are not supported by the current version of WAAPI.
wwise.core Overview
As an essential part of WAAPI, the wwise.core
APIs are very powerful. Aside from wwise.core
and soundengine
, the remaining execution APIs are relatively simple. In this blog, I will focus on wwise.core
.
From the mind map shown above, we can see that these APIs are primarily for Wwise audio design instead of sound engine configuration. If you are interested in optimizing Wwise operations, this blog can be very helpful.
Note: As shown above, those with a strikethrough have been replaced by new APIs.
audio (Importing Audio Files and Creating Wwise Objects)
Features
There are two APIs under the audio branch: import
and importTabDelimited
. As their names suggest, they are used to import audio assets. The former simply imports audio files and creates Wwise objects. The latter allows you to import audio files based on the rules specified in a tab-delimited file, and execute certain operations.
importTabDelimited imports the predefined information from a tab-delimited text file. This information includes the local directories of audio files, different Wwise hierarchies under which the objects are located (containers, Events, Output Busses), and how to make a reference to the property values or use Switches to assign child elements etc.
The text file can be generated by Microsoft Excel or other spreadsheet applications. Its first row defines the properties specified by each column heading. Each column determines what will be created in the Wwise project.
Usage
Obviously, audio
is the most important branch in terms of asset importing. These APIs eliminate the need for repetitive operations when you manually import a large number of files. With proper information specified, they can automatically set up the hierarchies, properties, streams etc.
Using import
to import audio files, you need to specify the directories and properties in their filenames. To this end, you must create a dictionary to map the designation indicated by these filenames, reducing the possibility of reporting errors due to long filenames.
Operation systems have a certain limit on the filename and path. Technically, the filename in Wwise must be no longer than 256 characters. Otherwise, the importing operation could fail. Taking the system path into account, users usually don’t have many characters to use.
In this case, we can use importTabDelimited
to import audio files from a tab-delimited text file in which certain rules are specified. In fact, this process can be further optimized. For example, sound designers can build a simple app with VBA to quickly generate tab-delimited files through Excel, or build a more complex GUI app with Python to create these files directly.
audioSourcePeaks (Getting Peak Values)
Features
There are two APIs under this branch: getMinMaxPeaksInRegion
and getMinMaxPeaksInTrimmedRegion
. They are used to get the peak values and return certain information. The former gets the peak values in the given region of an audio source. The latter gets the peak values in the entire trimmed region of an audio source. Note that we are not talking about just the Max Peak, but a Min/Max Peak pair specified by the numPeaks argument.getMinMaxPeaksInRegion
has two arguments: timeFrom
and timeTo
. They determine the start and end time of the section of the audio source for which peaks are required. For getMinMaxPeaksInTrimmedRegion
, you don’t have to specify the start and end time, it just evaluates the values after the SFX object is trimmed.
Both of these APIs return base-64 encoded, 16-bit signed integer arrays. They need to be decoded, parsed in a given format (fmt), then converted into dB values.
Usage
I’m new to Wwise plug-in development. As far as I know, you don’t have to take so many Min/Max Peak values from a single audio source. However, if you do, you can use these two APIs to calculate the peaks globally across channels. They can provide you with up to 14294967295 such values.
Object (Object Operations)
Features
create, copy, delete, move (Basic Object Operations)
These four APIs are used to execute the most basic object operations. They have arguments to define the object name, type, source path, target path etc.create
allows you to create massive objects that are listed in the Wwise Objects Reference document. import
and importTabDelimited
, by contrast, can only create audio-related objects (containers, Events etc.).
With create
, you can create Sound SFX objects, Work Units, containers, even effects and source plug-ins.
setReference, setRandomizer, setAttenuationCurve, setName, setNotes, setProperty (Setting Object Properties)
create
can only set a few object properties (such as notes). To set more object properties, you have to use the APIs listed above.setReference
sets an object’s reference value. For instance, you may set a reference to an Output Bus for a Sound SFX object.
As for setRandomizer
, setAttenuationCurve
, setName
and setNotes
, they just do what their names suggest.setProperty
sets a property value of an object for a specific platform. To learn more about the properties available on each object type, refer to the Wwise Objects Reference doc.
For example, if you want to set a property within the Mastering Suite, all you need is provide its location information such as GUID or path, then change the “property” key value to the name of the property that you’d like to modify, and finally specify an appropriate value to replace with.
get, getTypes, getPropertyInfo, getAttenuationCurve, getPropertyAndReferenceNames (Getting Object Properties)
If you want to get information on the current project, the APIs above will be your solution.get
is a query-based API. It returns different types of information such as ID, name, size, path, duration etc. You can get what you want by simply setting an appropriate query parameter. As mentioned in Part 1, it can pass in arguments from both tables (Arguments and Options), and get the return result based on what you choose from the Options table.
So, what’s the difference between them?
In the Arguments table, there are two arguments: from
and transform
.
from
indicates the data source of your query. You can search an object by its name, GUID, path, type etc. Also, you can filter a range of objects by specifying a sub-argument such asofType
orsearch
.transform
is used to transform a selected object. Let’s say we set a Random Container with from, then added select parent intransform
. In result, its parent object will be selected instead. So,transform
is an important complement tofrom
. It allows you to search the parent, children or reference based on what you set infrom
.
In the Options table, there are also two arguments: return
and platform
. (Note: these arguments can be left empty.)
return
specifies what return result you will get after the query process. The GUID and name of the object will be returned if left empty.platform
specifies which platform will be queried. The default platform will be queried if left empty.
Now, why do we need getTypes
, getPropertyInfo
, getAttenuationCurve
, getPropertyAndReferenceNames
?
Actually, those APIs are designed differently for various purposes. get
queries an object to get its general properties. The other four get the meta properties: getTypes
returns the types of all currently registered objects; getPropertyInfo
returns specific info about the object properties (such as value range); getAttenuationCurve
returns the Attenuation Curve settings of a specific object; getPropertyAndReferenceNames
returns the object properties and current reference names.
Usage
There are a variety of situations in which you can use these APIs. Some examples are getting the converted size of an audio file, getting the properties and reference names of an object, querying all the platforms in your project or all the Output Busses in use, etc.
It should be easier if you are familiar with the Queries tab in Wwise.
getInfo and log.get (Getting Project Info and Logs)
Features
These two APIs are used to simply get certain information. getInfo
returns global info of the current project, such as Wwise version, platform info, WAAPI version etc. log.get
returns the latest log. In fact, the tabs in the Logs window are linked to the channel
argument here.
If you want to update the log dynamically within your own app, certain subscription APIs can be helpful. (We will talk about this later.) Take ak.wwise.core.log.itemAdded
for example. This API returns info when an object is added.
Usage
You can use these two APIs as needed. For example, using log.get
to save each log to the database after you execute certain operations, or carry out further analysis so that you can get more customized feedback reports.
profiler (Profiler Operations)
Features
startCapture, stopCapture (Switching On/Off Capture)
These two APIs are used to simply start and stop the Profiler Capture process, without having to set any arguments.
getBusses, getCursorTime, getRTPCs, getVoiceContributions, getVoices (Getting Info at A Specific Profiler Capture Time)
getBusses
, getRTPCs
and getVoices
are similar. They just pass in a time value and get certain information such as bus gain, RTPC ID, RTPC value, voices etc.getCursorTime
returns the current time of the specified profiler cursor, in milliseconds.getVoiceContributions
returns all parameters affecting the dry path, such as voice volume, high-pass, low-pass etc.
Note that, for getBusses
and getVoices
, it’s possible to pass in two arguments, with the second defining the query range.
Usage
You can integrate the startCapture
and stopCapture
features into certain tools for manual or auto control, facilitating more complex capture process. For example, using the Unity WAAPI client to add some profiling capabilities and control the start and stop of capture, then you will get the profiling data for further analysis as needed.
project.save (Saving Projects)
Features
This API is used to save the current project.
Usage
Instead of simply replacing the Ctrl + S operation, this API automatically saves the project based on certain trigger conditions, without sacrificing the performance.
For example, when importing tens of thousands of files at one time or performing other batch processes, you could make a call to this API for every 100 or even 10 files, avoiding potential risks.
remote (Remote Connecting to Game)
Features
connect, disconnect (Switch On/Off Connection)
These two APIs are used to remotely connect to and disconnect from a game. By doing this, you have to provide the host IP and optional ports. And that’s why we need getAvailableConsoles
listed below. If you want to connect to different game engines, you can use it to get the available clients first.
getAvailableConsoles, getConnectionStatus (Getting Available Consoles and Checking Connection Status)
getAvailableConsoles
retrieves all consoles available for connecting Wwise Authoring to a Sound Engine instance, then returns the editor name, IP, port, platform etc.getConnectionStatus
checks the current connection status. Only connected game engines will return their console info and connection status.
Usage
The connection and disconnection features can be integrated into your game menus as described in One Minute Wwise so that you can click and connect to or disconnect from a game quickly. Also, you can use tools like StreamDeck or Metagrid to automatically trigger Python scripts to activate the remote connection, reducing the time wasted on manual operations.
You can combinegetAvailableConsoles
and getConnectionStatus
to integrate the Wwise Profiler data into your own app (refer to the “profiler” section). For example, automatically retrieving desired info, or just informing user of the current connection status in your own app, allowing for a better workflow outside of Wwise.
soundbank (SoundBank Generation and Settings)
Features
generate
, as its name suggests, generates a list of SoundBank. In addition to simply generating all SoundBanks, you may check specific SoundBanks, Platforms or Languages and click Generate Selected. Instead of doing this manually, you can let generate
do it for you.getInclusions
retrieves a SoundBank’s inclusion list, including the GUID, name, or path of the SoundBank to add an inclusion to.setInclusions
modifies a SoundBank’s inclusion list. You may add, remove and replace the SoundBank’s inclusion list.
Usage
soundbank
类中如果想对不存在的 SoundBank 进行内容设置,需先通过 create
进行创建 SoundBank 对象和层级,之后才能继续设置包内内容。
至此,一套完整的创建工作流就产生了,audio
类负责导入音频并创建音频层级结构,create
类可以创建并构建各种其他层级和 Event 等,最后由 soundbank
类负责收尾创建 SoundBank。这套工作流可用于根据外部设定的结构文件自动化创建,或在 Wwise 外的控制程序上通过 soundbank
检视工程内部结构。
A SoundBank has to be created before you set its inclusion list. And you can use create
to create a SoundBank’s objects and hierarchies.
So to conclude, the audio
branch APIs import audio files and create objects; the create
branch APIs create and build hierarchies, Events etc.; the soundbank
branch APIs create SoundBanks. This workflow can be used to automate the asset creation through externally defined structural files, or inspect the internal structure of a project via soundbank
in an app outside of Wwise.
switchContainer (Switch Container Operations)
Features
As mentioned previously, you can use the create branch APIs to create containers, including Switch Containers. Now why do we need switchContainer
?
Switch Containers won’t work unless they are assigned to Switch/State Groups, and each Switch/State has objects assigned.
You can use the switchContainer
branch APIs to make these assignments.addAssignment
assigns a Switch Container’s child to a Switch. removeAssignment
removes an assignment between a Switch Container’s child and a State. All you have to do is provide the GUIDs of objects within a Switch Container and the GUIDs of Switch/States within a Switch/State Group.getAssignments
returns the list of assignments between a Switch Container’s children and states.
Usage
The switchContainer
branch APIs can be used as a complement to the automated import workflow by assigning Switch elements to the containers that you created.
transport (Transport Control)
Features
create, destroy, executeAction
create
creates a transport object for the given Wwise object.destroy
destroys the given transport object. For create, you need to provide the Wwise object’s GUID. For destroy, you need to provide the transport object’s GUID.
So, what is a transport object? In fact, you are always repeating these two actions in your daily work within Wwise.
For example, when you select Event A, the Transport Control stays focused on it. In other words, you created an Event A transport object. If you select Event B, then Event A will be destroyed, and an Event B transport object will be created. If you click the Pin icon in the Transport Control view, the current transport object will persist, and no other transport objects will be created.
A Soundcaster Session is actually a collection of transport objects.executeAction
executes an action on the given transport object. There are five possible action values: play, stop, pause, playStop and playDirectly.
getList, getState
getList
returns the list of transport objects. You can view all of the transport objects unless they are destroyed with destroy.getState
gets the state of the given transport object. You can query the state with this API after executing an action with executeAction.
Usage
The transport
branch APIs can be used to define the playback behavior in an app outside of Wwise. This external app can be your own integration tool. You may use it to preview the sounds in your Wwise project or even replicate a Soundcaster Session outside of Wwise.
undo (Undo)
Features
People who are familiar with ReaScript can think of beginGroup
and endGroup
as Undo_BeginBlock()
and Undo_EndBlock()
in Reaper. beginGroup
begins an undo group. endGroup
ends the last undo group. beginGroup
can be used repeatedly.cancelGroup
cancels the last undo group.
Usage
An undo group is used to cancel a sequence of actions at once. Technically, it can also be used to redo these actions. However, WAAPI only supports undo for now. So, we will have to have to wait for future Wwise API updates. The undo
branch APIs added the possibility to cancel actions outside of Wwise.
Summary
You may forget what you’ve learned if you don’t practice. And this is why I suggest you make your own list according to the description in Part 1.
To utilize WAAPI, you should:
- Summarize WAAPI essentials by yourself, with or without mind maps.
- Open your mind and identify the pain-points in your audio design and integration workflow.
- Figure out the basic logics, and determine which APIs to use.
- Write the code to actually implement your ideas.
Use Cases
Let’s have a look at some real WAAPI use cases.
These use cases focus on implementing essential features. Interactive design and GUI are not our main concerns here. You can refer to these code lines and write your own code as needed.
I tried to cover as many wwise.core APIs as I could. I encourage you to keep researching those which I haven’t covered.
If you have bugs reported, double check your code, you should be able to pinpoint what the problem is.
For simplicity, I encapsulated each API into a function. You may modify the sample code described in the “Execution APIs” section (Part 1) as needed.
The directory structure of Wwise on macOS differs from that of Windows. MacOS users should pay attention to the file path. (In the Wwise Launcher, go to PROJECTS > RECENT PROJECTS > show more >>.)
1. You import a Sound SFX object, build the hierarchies, set the properties, create an Event, and set the action type. Then you create a SoundBank, add the newly created Event, and generate that SoundBank.
By quickly importing audio files into Wwise and creating proper hierarchies or even Events, you can greatly increase the efficiency of your audio integration. In the following example, usually we need to populate the arguments with file path, properties and hierarchies by hand. Or, we can just execute these repetitive tasks with WAAPI.
In order to quickly import audio assets into the Wwise project, you can utilize certain naming convention, database interaction and/or regular expressions to prepare the meta data first, then use the programming language of your choice to convert the formatted files into JSON arguments required for WAAPI importing.
Choosing APIs
- Importing files:
import
- Setting properties:
setProperty
- Creating Events, adding sounds, creating SoundBanks:
create
- Setting inclusions and generating SoundBanks:
setInclusions
,generate
Writing Code
1 | # 1. Import audio files and create hierarchy |
2. You get the global info of the current project as well as the Sound SFX size and SoundBank path.
Choosing APIs
- Getting the global info:
getInfo
- Getting the converted size of the Sound SFX object:
get
- Getting the SoundBank path:
get
Writing Code
1 | # 1. Get global information |
3. You re-create a Soundcaster Session and control the playback behavior.
Soundcaster has two main purposes: 1. Saving a group of transport objects for reuse (Soundcaster Session); 2. Controlling the Game Syncs, object properties, M/S etc. during playback.
Here we look at how to re-create a Soundcaster Session.
Note: The transport objects in WAAPI cannot be saved with the Wwise project. To implement the Soundcaster Session features, you need to save the GUID of each session separately for re-creating those transport objects next time.
Choosing APIs
- Transport control:
transport
Writing Code
1 | # 1. Create a Transport Object for the object, and the GUID of the transport object will be returned after creation. For management convenience, we put the object name and the GUID of the transport strip object in the same dictionary as the function return value |
4. You capture the Profiler data and generate a report.
Choosing APIs
- Switching on/off the capture:
startCapture
,stopCapture
- Capturing the data:
getBusses
,getCursorTime
,getRTPCs
,getVoiceContributions
,getVoices
Writing Code
1 | # 1. Start profiler data acquisition, and return to the start time |
What’s Next?
In Part 3, we will talk about the remaining execution APIs, including wwise.ui, wwise.waapi, wwise.debug and soundengine.